# coding:utf-8
# https://www.cnblogs.com/zhiyiYo/p/15676079.html
import os
import sys
import time
import resources.resource_rc
from PyQt5.QtCore import QRect, QRectF, QSize, Qt, QCoreApplication, pyqtSignal, QPoint, QDir, QTimer
from PyQt5.QtGui import QPainter, QPixmap, QWheelEvent, QKeySequence, QPen, QFont, QBrush, QCursor
from PyQt5.QtWidgets import (QApplication, QGraphicsItem, QGraphicsPixmapItem, QGraphicsSimpleTextItem,
                             QGraphicsScene, QGraphicsView, QShortcut, QFileDialog, QFrame)

from utils.pictureHandlers import PicturesReader
from serialPort import cm3_pb2


class PicturesPlayWindow(QGraphicsView):
    """ 图片查看器 """

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        # 引入公共程序
        from utils.common import commonProgram
        # 引入配置文件
        self.myConfig = commonProgram.EnableConfigHandler()
        print('PicturesPlayWindow get config Version', self.myConfig.version)
        # 引入可控串口信息窗口
        commonProgram.EnableSerialPort(RecvSerialData=self.RecvSerialData)
        # 更新图片路径
        commonProgram.UpdatePicturesPath()
        # 引入测试记录模块
        self.logsRecorder = commonProgram.EnableLogsRecorder()

        self.zoomInTimes = 0
        self.maxZoomInTimes = 22
        # 快捷键
        screenShortcut = QShortcut(QKeySequence(Qt.Key_F11), self)
        screenShortcut.activated.connect(self.WindowSizeFun)
        self.screenStatus = 'Normal'
        # 创建场景
        self.graphicsScene = QGraphicsScene()

        # 图片
        self.picturesReader = PicturesReader()
        self.picturesReader.OpenDirectory(picturesPath=self.myConfig.testPicturesPath)
        # self.picturesReader.FolderPrevious()
        self.pixmap = QPixmap()
        self.pixmapItem = QGraphicsPixmapItem(self.pixmap)
        self.displayedImageSize = QSize(0, 0)
        # 测试记录
        # self.testDetailWin = TestDetailWindow()
        # self.toTestDetailSignal.connect(self.testDetailWin.RecvMainData)
        if len(self.picturesReader.file_paths) == 0:
            tipText = QGraphicsSimpleTextItem('没有发现图片,\n  请在文件夹"data/pattern/<分辨率>/中放入需要显示的图片\n  放入完成后重新打开程序即可"')
            tipText.setPos(0, 0)
            tipText.setPen(QPen(Qt.red))
            tipText.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
            # tipText.setScale(1.5)
            tipText.setFont(QFont(self.font().family(), 15))
            self.graphicsScene.addItem(tipText)
        else:
            for item in self.picturesReader.file_paths:
                emitData = {'status': False, "item": item, "remarks": '', 'type': 0, }
                # self.toTestDetailSignal.emit(emitData)
                # self.testDetailWin.show()
        # 初始化小部件
        self.__initWidget()
        self.graphicsScene.clearSelection()  # 【清除选择】

        self.WindowSizeFun()
        # self.setImage(":/pictures/pictures/00-userGuidePicturesPlay.png")

        # self.myInit = False
        self.myEnd = False

        # 播放第一张图片
        # self.setImage(self.picturesReader.FolderCurrent())
        # self.change_img_timer = QTimer()
        # self.change_img_timer.timeout.connect(self.ChangeImg)
        # self.change_img_timer.start(1000)

    # def ChangeImg(self):
    #     self.change_img_timer.stop()
    #     self.setImage('./data/pattern/2400x1200/01_Flicker.bmp')
    #     if self.picturesReader.file_index >= len(self.picturesReader.file_paths) - 1:
    #         self.picturesReader.file_index = 0
    #     self.change_img_timer.start(2000)

    def RecvSerialData(self, dictData: dict):
        # 用于接收Form2发过来的数据
        # dataStr = dictData.get("data", None)  # num2 就是子界面传递过来的数据
        if self.isVisible():
            self.DataHandleFun(dictData)
        # # type: send-发往串口，statusbar-显示在statusbar(状态栏)，text,.., - 显示在 textBrowser, null-不需要显示
        # print('-'*30)

    def DataHandleFun(self, dataDict: dict):
        typeStr = dataDict.get('type', 'null').strip()
        if typeStr == 'rece_protobuf':
            display = dataDict.get('data', '')
            # print(display)
            if display.msg_type == cm3_pb2.Image:
                imgIdx = display.image.index
                # print(imgIdx)
                try:
                    imgPath = self.picturesReader.image_dict.get(imgIdx, None)
                    # print(imgPath)
                    if imgPath:
                        self.setImage(imgPath)
                        dictData = {
                            "index": imgIdx,
                            "file": os.path.basename(imgPath),
                        }
                        self.logsRecorder.ImageFun(dictData)
                except Exception as e:
                    print('picture:', e)
            if self.myEnd == True:
                self.myConfig.itemLock = 0
                return
            if display.msg_type == cm3_pb2.Input:
                if display.input.key == 2:
                    self.setImage(self.picturesReader.FolderPrevious())
                elif display.input.key == 4:
                    self.setImage(self.picturesReader.FolderNext())
                    # self.timeoutTimer.start(1000)
            if (self.picturesReader.file_index >= len(self.picturesReader.file_paths) - 1) or (
                    self.picturesReader.file_index <= 0):
                # self.pixmapPass.setVisible(True)
                # self.myConfig.passItems.append('PicturesTest')
                self.myEnd = True
                self.myConfig.passTestItems.add('PicturesPlay')
            else:
                self.myEnd = False

    def WindowSizeFun(self, toStatus='Normal'):
        # print(toStatus)
        if self.screenStatus == 'Normal' or toStatus == 'FullScreen':
            self.showFullScreen()
            self.screenStatus = 'FullScreen'
            # self.displayedImageSize = self.rect().size()
            # self.resize(self.myConfig.screenLength,self.myConfig.screenWidth)
            # self.fitInView(self.pixmapItem, Qt.KeepAspectRatio)
            # self.zoomIn()
            # self.graphicsScene.setSceneRect(QRectF(self.rect()))
            # print(self.graphicsScene.sceneRect())
            # print(self.rect())
        else:
            self.showNormal()
            self.screenStatus = 'Normal'
        # print('WindowSizeFun')

    def __initWidget(self):
        """ 初始化小部件 """
        # self.resize(1200, 900)
        # 窗体置顶(窗体置顶，仅仅为了方便测试)，去边框
        # self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
        # self.setStyleSheet("border-width: 0px; border-style: solid")
        # self.setStyleSheet("border: 0px")
        # self.setWindowFlags(Qt.FramelessWindowHint)  # 无边框
        self.setFrameStyle(QFrame.NoFrame)  # 无Frame边框
        self.setCursor(QCursor(Qt.BlankCursor))  # 隐藏鼠标
        self.setBackgroundBrush(QBrush(Qt.black))  # 黑色背景
        # 隐藏滚动条
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # 以鼠标所在位置为锚点进行缩放
        self.setTransformationAnchor(self.AnchorUnderMouse)

        # 平滑缩放
        self.pixmapItem.setTransformationMode(Qt.SmoothTransformation)
        self.setRenderHints(QPainter.Antialiasing |
                            QPainter.SmoothPixmapTransform)

        # 设置场景
        self.graphicsScene.addItem(self.pixmapItem)
        self.setScene(self.graphicsScene)
        # self.setToolTip("上一张：单击左边\n下一张：单击右边\n全  屏：F11 或 单击上边\n退全屏：单击下边")
        # 通过图标
        self.pixmapPass = QGraphicsPixmapItem(QPixmap(':/icons/icons/pass.png'))
        self.pixmapPass.setScale(0.5)
        self.pixmapPass.setZValue(1)
        self.pixmapPass.setPos(self.myConfig.screenLength / 2, self.myConfig.screenWidth / 2 - 100)
        self.pixmapPass.setVisible(False)
        self.graphicsScene.addItem(self.pixmapPass)

    # def wheelEvent(self, e: QWheelEvent):
    #     """ 滚动鼠标滚轮缩放图片 """
    #     if e.angleDelta().y() > 0:
    #         self.zoomIn()
    #     else:
    #         self.zoomOut()

    # def mousePressEvent(self, evt):
    #     self.item = self.get_item_at_click(evt)
    #     pt = evt.pos()  # 获取鼠标坐标--view坐标
    #     QGraphicsView.mousePressEvent(self, evt)
    #     # if self.myInit == False:
    #     #     self.myInit = True
    #     #     self.setImage(self.picturesReader.FolderCurrent())
    #     #     return
    #     if self.myEnd == True:
    #         self.pixmapPass.setVisible(True)
    #         self.myConfig.passItems.append('PicturesTest')
    #     if self.item is not None:
    #         pass
    # print('self.item: ', self.item)
    # viewW, viewH = self.rect().width(), self.rect().height()
    # viewCoordX, viewCoordY = QPoint(pt).x(), QPoint(pt).y(),  # 转为QPoint可提取X,Y值
    # if viewCoordX < viewW / 4:
    #     print('单击左边，上一张', viewW, viewH)
    #     self.setImage(self.picturesReader.FolderPrevious())
    # elif viewCoordX > viewW * 3 / 4:
    #     print('单击右边，下一张', viewW, viewH)
    #     self.setImage(self.picturesReader.FolderNext())
    #     if self.picturesReader.file_index >= len(self.picturesReader.file_paths) - 1:
    #         self.myEnd = True
    #         # self.timeoutTimer.start(1000)
    # elif viewCoordY < viewH / 4:
    #     print('单击上边，全屏', viewW, viewH)
    #     self.WindowSizeFun(toStatus='FullScreen')
    # elif viewCoordY > viewH * 3 / 4:
    #     print('单击下边，推出全屏', viewW, viewH)
    #     self.WindowSizeFun(toStatus='Normal')

    def get_item_at_click(self, e):
        pos = e.pos()
        item = self.itemAt(pos)
        return item

    # def resizeEvent(self, e):
    #     """ 缩放图片 """
    #     super().resizeEvent(e)
    #
    #     if self.zoomInTimes > 0:
    #         return
    #
    #     # 调整图片大小
    #     ratio = self.__getScaleRatio()
    #     self.displayedImageSize = self.pixmap.size() * ratio
    #     if ratio < 1:
    #         self.fitInView(self.pixmapItem, Qt.KeepAspectRatio)
    #     else:
    #         self.resetTransform()

    def setImage(self, imagePath: str):
        """ 设置显示的图片 """
        self.resetTransform()

        # 刷新图片
        self.pixmap = QPixmap(imagePath)
        self.pixmapItem.setPixmap(self.pixmap)

        # 调整图片大小
        self.setSceneRect(QRectF(self.pixmap.rect()))
        # ratio = self.__getScaleRatio()
        # self.displayedImageSize = self.pixmap.size() * ratio
        # if ratio < 1:
        #     self.fitInView(self.pixmapItem, Qt.KeepAspectRatio)
        # self.fitInView(self.pixmapItem, Qt.KeepAspectRatio)
        # self.zoomIn()

    # def resetTransform(self):
    #     """ 重置变换 """
    #     super().resetTransform()
    #     self.zoomInTimes = 0
    #     self.__setDragEnabled(False)

    # def __isEnableDrag(self):
    #     """ 根据图片的尺寸决定是否启动拖拽功能 """
    #     v = self.verticalScrollBar().maximum() > 0
    #     h = self.horizontalScrollBar().maximum() > 0
    #     return v or h

    # def __setDragEnabled(self, isEnabled: bool):
    #     """ 设置拖拽是否启动 """
    #     self.setDragMode(
    #         self.ScrollHandDrag if isEnabled else self.NoDrag)

    # def __getScaleRatio(self):
    #     """ 获取显示的图像和原始图像的缩放比例 """
    #     if self.pixmap.isNull():
    #         return 1
    #
    #     pw = self.pixmap.width()
    #     ph = self.pixmap.height()
    #     rw = min(1, self.width() / pw)
    #     rh = min(1, self.height() / ph)
    #     return min(rw, rh)

    # def fitInView(self, item: QGraphicsItem, mode=Qt.KeepAspectRatio):
    #     """ 缩放场景使其适应窗口大小 """
    #     super().fitInView(item, mode)
    #     self.displayedImageSize = self.__getScaleRatio() * self.pixmap.size()
    #     self.zoomInTimes = 0

    # def zoomIn(self, viewAnchor=QGraphicsView.AnchorUnderMouse):
    #     """ 放大图像 """
    #     if self.zoomInTimes == self.maxZoomInTimes:
    #         return
    #
    #     self.setTransformationAnchor(viewAnchor)
    #
    #     self.zoomInTimes += 1
    #     self.scale(1.005, 1.005)
    #     self.__setDragEnabled(self.__isEnableDrag())
    #
    #     # 还原 anchor
    #     self.setTransformationAnchor(self.AnchorUnderMouse)

    # def zoomOut(self, viewAnchor=QGraphicsView.AnchorUnderMouse):
    #     """ 缩小图像 """
    #     if self.zoomInTimes == 0 and not self.__isEnableDrag():
    #         return
    #
    #     self.setTransformationAnchor(viewAnchor)
    #
    #     self.zoomInTimes -= 1
    #
    #     # 原始图像的大小
    #     pw = self.pixmap.width()
    #     ph = self.pixmap.height()
    #
    #     # 实际显示的图像宽度
    #     w = self.displayedImageSize.width() * 1.005 ** self.zoomInTimes
    #     h = self.displayedImageSize.height() * 1.005 ** self.zoomInTimes
    #
    #     if pw > self.width() or ph > self.height():
    #         # 在窗口尺寸小于原始图像时禁止继续缩小图像比窗口还小
    #         if w <= self.width() and h <= self.height():
    #             self.fitInView(self.pixmapItem)
    #         else:
    #             self.scale(1 / 1.005, 1 / 1.005)
    #     else:
    #         # 在窗口尺寸大于图像时不允许缩小的比原始图像小
    #         if w <= pw:
    #             self.resetTransform()
    #         else:
    #             self.scale(1 / 1.005, 1 / 1.005)
    #
    #     self.__setDragEnabled(self.__isEnableDrag())
    #
    #     # 还原 anchor
    #     self.setTransformationAnchor(self.AnchorUnderMouse)

    def showEvent(self, event):
        # print('+' * 20, event)
        self.myConfig.itemLock = 1
        self.myEnd = False

    def closeEvent(self, a0):
        # print('-' * 20, a0)
        self.myConfig.itemLock = 0
        self.myEnd = False


if __name__ == '__main__':
    # QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    # 解决图片在不同分辨率显示模糊问题
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
    # QApplication.setAttribute( Qt.AA_Use96Dpi)
    app = QApplication(sys.argv)
    font = QFont("宋体")
    pointsize = font.pointSize()
    font.setPixelSize(int(pointsize * 90 / 72))
    app.setFont(font)
    # myWin = MyMainWindow()
    # mainWindow = ViewParamWindow()
    # mainWindow.show()
    # sys.exit(app.exec_())
    w = PicturesPlayWindow()
    w.show()
    sys.exit(app.exec())
